package com.ayf.payment.game.api.service.payment;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ayf.payment.game.api.bean.BaseResData;
import com.ayf.payment.game.api.channel.xingyou.util.XingYou2SignUtil;
import com.ayf.payment.game.api.dto.OrderAndMerchantDTO;
import com.ayf.payment.game.api.dto.platform.MerchantPaymentProductDTO;
import com.ayf.payment.game.api.dto.platform.PaymentChannelDTO;
import com.ayf.payment.game.api.entity.Order;
import com.ayf.payment.game.api.entity.Partition;
import com.ayf.payment.game.api.exception.NullSetException;
import com.ayf.payment.game.api.httpclient.HttpUtils;
import com.ayf.payment.game.api.type.OrderStatus;
import com.ayf.payment.game.api.utils.DateUtils;
import com.ayf.payment.game.api.utils.HtmlPayFormUtil;
import com.ayf.payment.game.api.utils.SnowFlakeUtils;
import com.swwx.charm.commons.lang.utils.LogPortal;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;


@Service
public class XingYou2PaymentService extends IPaymentService {

    @Override
    public Map<String, Object> paymentUtil(Order order, Partition partition, String orderCreateStr, String traceId, String redirectUrl) {
        Map<String, Object> map=new HashMap<>();
        MerchantPaymentProductDTO merchantPaymentProductDTO = systemInitialization.productDTO(order.getPayTypeId());
        PaymentChannelDTO paymentChannelDTO = systemInitialization.channelDTO(merchantPaymentProductDTO.getcId());
        BigDecimal actualOrderAmt = getActualOrderAmt(order.getAmount(),paymentChannelDTO.getId(),partition.getMerchantId());
        String orderCreateUrl = orderCreate(traceId,order,paymentChannelDTO,merchantPaymentProductDTO.getBusinessCode(),redirectUrl,actualOrderAmt);
        order.setRandomAmt(BigDecimal.ZERO);
        order.setOrderNo("");
        order.setPayChannleName(paymentChannelDTO.getName());
        order.setPayChannleId(paymentChannelDTO.getId());
        order.setPayTypeId(merchantPaymentProductDTO.getProductId());
        order.setPayTypeName(merchantPaymentProductDTO.getProductName());
        order.setMerchantIncome(BigDecimal.ZERO);
        order.setPlatformIncome(BigDecimal.ZERO);
        order.setFee(BigDecimal.ZERO);
        order.setChannelIncome(BigDecimal.ZERO);
        orderMapper.insertSelective(order);
        map.put("code","002");
        map.put("htmlMsg",orderCreateUrl);
        return map;
    }

    private String orderCreate(String traceId,Order order,PaymentChannelDTO paymentChannelDTO,String businessCode,String redirectUrl,BigDecimal actualOrderAmt){
        String KeyValue = paymentChannelDTO.getChannelKey();
        String parter = paymentChannelDTO.getAccountNumber();
        String returnUrl=paymentChannelDTO.getReturnUrl();
        String AuthorizationURL = paymentChannelDTO.getPaymentUrl();
        if (StringUtils.isEmpty(AuthorizationURL)){
            LogPortal.error("{} 失败，通道下单地址不能为空，订单号:{}",traceId,order.getMerchantOrderNo());
            throw new NullSetException(traceId + "下单失败，请稍后重试！");
        }
        if (!AuthorizationURL.endsWith("/")){
            AuthorizationURL=AuthorizationURL.concat("/");
        }
        AuthorizationURL=AuthorizationURL.concat("Pay.php");
        if (StringUtils.isEmpty(returnUrl)){
            LogPortal.error("{} 失败，异步通知地址不能为空，订单号:{}",traceId,order.getMerchantOrderNo());
            throw new NullSetException(traceId + "下单失败，请稍后重试！");
        }
        if (!returnUrl.endsWith("/")){
            returnUrl=returnUrl.concat("/");
        }

        if (!redirectUrl.endsWith("/")){
            redirectUrl=redirectUrl.concat("/");
        }

        Map<String,String> reqParam = new TreeMap<>();
        reqParam.put("BankCode",getPayCode(businessCode));
        reqParam.put("NotifyLink",returnUrl.concat("gameapip/v/xingyou2/pay/notify"));
        reqParam.put("PayMoney",String.valueOf(actualOrderAmt.setScale(2, BigDecimal.ROUND_DOWN)));
        reqParam.put("PayNames",order.getMerchantOrderNo());
        reqParam.put("PayTimes",String.valueOf(order.getCreateTime().getTime()/1000));
        reqParam.put("ReturnLink",redirectUrl.concat("gws/loading.html?orderNo=").concat(order.getMerchantOrderNo()));
        reqParam.put("UserTradeNo",order.getMerchantOrderNo());
        reqParam.put("UserUId",parter);

        String sign= XingYou2SignUtil.getSign(traceId,"星游2下单",reqParam,KeyValue);
        reqParam.put("Sign",sign);
        String result = HtmlPayFormUtil.packageHtmlPayementForm(reqParam,AuthorizationURL);
        LogPortal.info("{} 商户ID[{}] 商户订单号[{}] 星游2下单 请求报文[{}]", traceId, order.getMerchantId(), order.getMerchantOrderNo(),result);
        return result;
    }


    @Override
    public void queryPayOrder(OrderAndMerchantDTO dto, String traceId) {
        String methodDesc = "星游2订单查询";
        PaymentChannelDTO paymentChannelDTO = systemInitialization.channelDTO(dto.getPayChannleId());
        BaseResData baseResData = orderQuery(traceId,methodDesc,paymentChannelDTO,dto);
        if (baseResData.isProcessing()){
            return;
        }
        if (baseResData.isSuccess()){
            String result = baseResData.getData();
            JSONObject jsonData = JSONObject.parseObject(result);
            String code = jsonData.getString("code");
            if ("1".equals(code)){
               JSONArray jsonArray =  jsonData.getJSONArray("data");
                JSONObject jsonResult = jsonArray.getJSONObject(0);
                String status = jsonResult.getString("status"); // 订单状态
                if (StringUtils.isEmpty(status) || "3".equals(status)){
                    return;
                }
                String merchantOrderNo = jsonResult.getString("out_trade_no"); // 商户订单号
                String channelOrderNo = jsonResult.getString("trade_no"); // 支付接口订单号
                Order order = orderService.selectByMerchantOrderNo(merchantOrderNo);
                if (order == null) {
                    LogPortal.error("{} {} 商户订单号[{}]在我方系统查询不到", traceId,methodDesc,merchantOrderNo);
                    return;
                }
                OrderStatus orderStatus= OrderStatus.PROCESSING;
                if ("1".equals(status) || "2".equals(status)){ // 成功
                    orderStatus= OrderStatus.SUCCESS;
                }
                if (OrderStatus.PROCESSING.equals(order.getOrderStatus()) && !orderStatus.equals(OrderStatus.PROCESSING)) {
                    order.setOrderStatus(orderStatus);
                    order.setChannelRpsMsg("支付成功");
                    if (StringUtils.isNotEmpty(channelOrderNo)){
                        order.setOrderNo(channelOrderNo);
                    }
                    orderService.paymentOrder(order, new JSONObject());
                    if (OrderStatus.SUCCESS.equals(order.getOrderStatus())) {
                        orderService.orderToGetWay(order);
                        wxSendMsgUtils.rechargeSuccess(order);
                    }
                }
            } else {
                String message = jsonData.getString("message");
                LogPortal.error("{} {} 查询通道返回错误码:{} 错误描述:{}",traceId,methodDesc,code,message);
            }
        }
    }

    private BaseResData orderQuery(String traceId,String methodName,PaymentChannelDTO paymentChannelDTO,OrderAndMerchantDTO dto){
        String AuthorizationURL = paymentChannelDTO.getPaymentUrl();
        String orderNo = dto.getMerchantOrderNo();
        if (StringUtils.isEmpty(AuthorizationURL)){
            LogPortal.error("{} 失败，通道下单地址不能为空，订单号:{}",traceId,dto.getMerchantOrderNo());
            throw new NullSetException(traceId + "下单失败，请稍后重试！");
        }
        if (!AuthorizationURL.endsWith("/")){
            AuthorizationURL=AuthorizationURL.concat("/");
        }
        AuthorizationURL=AuthorizationURL.concat("QueryOrder.php");


        Map<String,String> reqParam = new TreeMap<>();
        reqParam.put("UserTradeNo",orderNo);
        reqParam.put("UserUId",paymentChannelDTO.getAccountNumber());

        String sign =XingYou2SignUtil.getSign(traceId,methodName,reqParam,paymentChannelDTO.getChannelKey());
        reqParam.put("Sign",sign);
        BaseResData result = HttpUtils.sendPostForm(traceId,methodName,AuthorizationURL,reqParam);
        return result;
    }


    private String getPayCode(String code){
        if("ALIPAY".equals(code)||"ANTCREDITPAY".equals(code)){
            return "90002";
        } else if("WECHAT".equals(code)){
            return "90003";
        } else {
            throw new NullSetException("该通道不支持充值，请更换其他通道充值！");
        }
    }

    private static void testOrderCreate(){
        PaymentChannelDTO paymentChannelDTO = getTestPaymentChannelDTO();
        String businessCode = "ALIPAY";// 支付宝
//        String businessCode = "WECHAT";// 微信
        Order order = new Order();
        Date currentDate = DateUtils.getNowDate();
        String orderCreateStr = DateUtils.dateToString(currentDate, DateUtils.formatPattern_full_03);
        String orderNo = "M" + orderCreateStr + SnowFlakeUtils.getUniqueId();
        order.setMerchantOrderNo(orderNo);
        order.setCreateTime(currentDate);
        order.setAmount(BigDecimal.valueOf(1));
        order.setMerchantId(1000);
        String traceId = SnowFlakeUtils.getTraceId28();
        String redirectUrl = "http://uatxy.xyouplay.com";
        BigDecimal orderAmt = BigDecimal.valueOf(1);
        XingYou2PaymentService xingYou2PaymentService = new XingYou2PaymentService();
        String payUrl = xingYou2PaymentService.orderCreate(traceId,order,paymentChannelDTO,businessCode,redirectUrl,orderAmt);
        System.out.println("星游2下单返回下单URL="+payUrl);
    }


    private static void testOrderQuery(){
        PaymentChannelDTO paymentChannelDTO = getTestPaymentChannelDTO();
        String traceId = SnowFlakeUtils.getTraceId28();

        OrderAndMerchantDTO dto = new OrderAndMerchantDTO();
        dto.setMerchantId(1000);
        dto.setMerchantOrderNo("M".concat(traceId));
        XingYou2PaymentService xingYou2PaymentService = new XingYou2PaymentService();
        BaseResData result = xingYou2PaymentService.orderQuery(traceId,"星游2订单查询",paymentChannelDTO,dto);
        System.out.println("星游2订单查询返回结果:"+result);
    }


    private static PaymentChannelDTO getTestPaymentChannelDTO(){
        PaymentChannelDTO paymentChannelDTO = new PaymentChannelDTO();
        paymentChannelDTO.setPaymentUrl("http://aapi.000zf.com");
        paymentChannelDTO.setReturnUrl("http://uatxy.xyouplay.com");
        paymentChannelDTO.setChannelKey("zG9Ts5G93n3G5GxzyZ7LUrW1XxuD79N3");
        paymentChannelDTO.setAccountNumber("3167");
        return paymentChannelDTO;
    }

    public static void main(String[] args) {
//        testOrderCreate();
        testOrderQuery();
    }

}
